use crate::common::{AppState, Response};
use crate::error::AppError;
use crate::models::files::MyFile;
use axum::extract::{Multipart, State};
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::sync::Arc;

pub async fn upload_file(
    State(app_state): State<Arc<AppState>>,
    mut multipart: Multipart,
) -> Result<Response<String>, AppError> {
    let user = app_state.user.lock().unwrap().clone().unwrap();

    while let Some(field) = multipart.next_field().await.unwrap() {
        if field.name() == Some("file") {
            let filename = field.file_name().unwrap().to_string();
            let data = field.bytes().await.unwrap();

            // 创建文件保存路径 (建议使用绝对路径)
            let save_path = format!("/tmp/uploads/{filename}");
            let path = Path::new(&save_path);

            // 创建目录（如果不存在）
            if let Some(parent) = path.parent() {
                tokio::fs::create_dir_all(parent).await?;
            }

            // 写入文件
            let mut file = File::create(path)?;
            file.write_all(&data)?;

            //插入数据库
            let res = app_state
                .insert_file(&MyFile {
                    id: Default::default(),
                    name: filename.to_string(),
                    path: path.to_str().unwrap().to_string(),
                    size: file.metadata()?.len() as i32,
                    user_id: user.id as i32,
                    file_type: "file".to_string(),
                    created_at: Default::default(),
                    updated_at: Default::default(),
                })
                .await
                .unwrap();

            return Ok(Response::ok(res.to_string()));
        }
    }
    Err(AppError::UploadFileError("file not found".to_string()))
}
